package com.quick.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.quick.base.BaseUser;
import com.quick.base.KeyValue;
import com.quick.base.Page;
import com.quick.base.QueryParam;
import com.quick.base.Search;
import com.quick.config.QuickSystem;
import com.quick.exception.QuickStateEnum;
import com.quick.mapper.SysUserMapper;
import com.quick.service.IQuickService;
import com.quick.service.ISysUserRoleService;
import com.quick.service.ISysUserService;
import com.quick.sys.domain.dto.SysUserDTO;
import com.quick.sys.domain.dto.SysUserLoginDTO;
import com.quick.sys.domain.pojo.SysUser;
import com.quick.sys.domain.vo.SysUserDetailVo;
import com.quick.sys.domain.vo.SysUserVo;
import com.quick.sys.domain.vo.UserLoginVo;
import com.quick.util.Convert;
import com.quick.util.JSONUtil;
import com.quick.util.PageUtil;
import com.quick.util.QuickTool;
import com.quick.util.TokenUtil;
import lombok.AllArgsConstructor;

import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class SysUserServiceImpl implements ISysUserService,IQuickService {

    private final SysUserMapper sysUserMapper;
    private final ISysUserRoleService userRoleService;
    private final RedisTemplate<String, String> redisTemplate;

    @Override
    public Page<SysUserVo> search(Search<SysUser> search) {
        PageHelper.startPage(search.getPageNum(),search.getPageSize());
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper(queryWrapper,search.getSearch());
        List<SysUser> list =sysUserMapper.selectList(queryWrapper);
        PageInfo<SysUser> pageInfo = new PageInfo<>(list);
        return PageUtil.page(pageInfo,SysUserVo.class);
    }

    @Override
    public UserLoginVo userLogin(SysUserLoginDTO login) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getName,login.getUsername());
        queryWrapper.lambda().eq(SysUser::getPassword,login.getPassword());
        SysUser user = sysUserMapper.selectOne(queryWrapper);
        QuickTool.isNull(user,"用户名或密码错误");
        String token = TokenUtil.generateKey();
        String uuid = QuickSystem.getKey(token);
        redisTemplate.opsForValue().set(uuid, JSONUtil.toStr(user));
        UserLoginVo loginVo = new UserLoginVo();
        loginVo.setToken(token);
        return loginVo;
    }

    @Override
    public SysUserDetailVo getUser() {
    	String fullKey = QuickSystem.getFullKey();
        Object source = redisTemplate.opsForValue().get(fullKey);
        QuickTool.isNull(source, QuickStateEnum.USER_LOGIN_INVALID);
        SysUser user = JSONUtil.toBean(source.toString(), SysUser.class);
        SysUserDetailVo target = new SysUserDetailVo();
        BeanUtils.copyProperties(user, target);
        QuickTool.isNullBlank(user.getRoles(), QuickStateEnum.CURRENT_USER_NOT_ROLE);
        List<Integer> roles = Arrays.stream(user.getRoles().split(",")).map(s->Integer.parseInt(s.trim())).collect(Collectors.toList());
        target.setRoles(roles);
        return target;
    }

    @Override
    public Boolean loginOut() {
        return redisTemplate.delete(TokenUtil.getToken());
    }

	@Override
	public Boolean saveUser(SysUserDTO user) {
		QuickTool.isNull(user, "参数不能为空");
		SysUser entity = Convert.convert(user, SysUser.class);
		if(QuickTool.notNull(entity.getId())) {
			QuickTool.setFillUpdate(entity);
			entity.setRoles(QuickTool.joiner(",", user.getRoles()));
			int row = sysUserMapper.updateById(entity);
			userRoleService.saveUserRole(user.getRoles(),entity.getId());
			return row>0;
		}
		checkUserName(user.getName());
		entity.setRoles(QuickTool.joiner(",", user.getRoles()));
		QuickTool.setFillInsert(entity);
		int row = sysUserMapper.insert(entity);
		userRoleService.saveUserRole(user.getRoles(),entity.getId());
		return row>0;
	}

	@Override
	public void checkUserName(String userName) {
		 QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
	     queryWrapper.lambda().eq(SysUser::getName,userName);
	     queryWrapper.lambda().or().eq(SysUser::getEmail,userName);
	     queryWrapper.lambda().or().eq(SysUser::getTel,userName);
	     SysUser user = sysUserMapper.selectOne(queryWrapper);
	     QuickTool.notNull(user, QuickStateEnum.USER_ALREADY_EXISTS);
	}

	@Override
	public Boolean delUser(Long id) {
		SysUser user = sysUserMapper.selectById(id);
		QuickTool.isTrue("admin".equals(user.getName()), QuickStateEnum.ADMINISTRATOR_NOT_DELETE);
		return sysUserMapper.deleteById(id)>0;
	}

	@Override
	public BaseUser getBaseUser(String fullKey) {
		Object res = redisTemplate.opsForValue().get(fullKey);
		return Convert.convert(res.toString(), BaseUser.class);
	}

	@Override
	public List<KeyValue> loadSysUserAll(QueryParam search) {
		List<KeyValue> values = new ArrayList<KeyValue>();
		 QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
		 if(QuickTool.notNull(search.getKey())) {
			 queryWrapper.lambda().like(SysUser::getName,search.getKey());
		     queryWrapper.lambda().or().like(SysUser::getEmail,search.getKey());
		     queryWrapper.lambda().or().like(SysUser::getTel,search.getKey());
		 }
	     List<SysUser> user = sysUserMapper.selectList(queryWrapper);
	     if(QuickTool.notNull(user)) {
	    	 user.forEach(e->{
	    		 values.add(new KeyValue(e.getName(), e.getId()));
	    	 });
	     }
		return values;
	}
}
